package com.sunnay.util;

import org.apache.commons.lang3.time.DateUtils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

public class LocalDateUtils {

    public static final String PATTERN_YYYY_MM_DD = "yyyy-MM-dd";
    public static final String PATTERN_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
    public static final String PATTERN_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    public static final String PATTERN_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public static final String PATTERN_YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd HH:mm:ss.SSS";
    public static final String PATTERN_HH_MM_SS = "HH:mm:ss";
    public static final String PATTERN_YYYYMMDD_SPLIT_BY_SLASH = "yyyy/MM/dd";
    public static final String PATTERN_YYYYMMDD_SPLIT_BY_POINT = "yyyy.MM.dd";
    public static final String PATTERN_YYYYMMDD_SPLIT_BY_CN = "yyyy年MM月dd日";
    public static final String PATTERN_YYYYMMDD_SPLIT_BY_CN_HH_MM = "yyyy年MM月dd日 HH:mm";
    public static final Integer SPRING = 1;
    public static final Integer SUMMER = 2;
    public static final Integer AUTUMN = 3;
    public static final Integer WINTER = 4;
    public static final String SUNDAY = "星期日";
    public static final String MONDAY = "星期一";
    public static final String TUESDAY = "星期二";
    public static final String WEDNESDAY = "星期三";
    public static final String THURSDAY = "星期四";
    public static final String FRIDAY = "星期五";
    public static final String SATURDAY = "星期六";
    private static final String YEAR = "year";
    private static final String MONTH = "month";
    private static final String WEEK = "week";
    private static final String DAY = "day";
    private static final String HOUR = "hour";
    private static final String MINUTE = "minute";
    private static final String SECOND = "second";
    private static String[] weekOfDays = new String[]{"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};
    private static Map<String, DateTimeFormatter> DF = new HashMap();

    public LocalDateUtils() {
    }

    private static DateTimeFormatter getDf(String pattern) {
        DateTimeFormatter dateTimeFormatter = (DateTimeFormatter)DF.get(pattern);
        if (dateTimeFormatter == null) {
            Class var2 = LocalDateUtils.class;
            synchronized(LocalDateUtils.class) {
                dateTimeFormatter = (DateTimeFormatter)DF.get(pattern);
                if (dateTimeFormatter == null) {
                    dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
                }
            }
        }

        return dateTimeFormatter;
    }

    public static String getLocalDateTimeStr() {
        return format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss");
    }

    public static String getLocalDateStr() {
        return format(LocalDate.now(), "yyyy-MM-dd");
    }

    public static String getLocalTimeStr() {
        return format(LocalTime.now(), "HH:mm:ss");
    }

    public static long getChronoUnitBetween(LocalDateTime start, LocalDateTime end, ChronoUnit chronoUnit) {
        return Math.abs(start.until(end, chronoUnit));
    }

    public static long getChronoUnitBetween(Date start, Date end, ChronoUnit chronoUnit) {
        LocalDateTime startTime = conversionDate2LocalDateTime(start);
        LocalDateTime endTime = conversionDate2LocalDateTime(end);
        return getChronoUnitBetween(startTime, endTime, chronoUnit);
    }

    public static long getChronoUnitBetween(LocalDate start, LocalDate end, ChronoUnit chronoUnit) {
        return Math.abs(start.until(end, chronoUnit));
    }

    public static String getDayOfWeekStr() {
        return format(LocalDate.now(), "E");
    }

    public static String getDayOfWeekStr(LocalDate localDate) {
        int dayOfWeek = localDate.getDayOfWeek().getValue() - 1;
        return weekOfDays[dayOfWeek];
    }

    public static String getFirstDayOfYearStr() {
        return getFirstDayOfYearStr(LocalDateTime.now());
    }

    public static String getLastDayOfYearStr() {
        return getLastDayOfYearStr(LocalDateTime.now());
    }

    public static String getFirstDayOfYearStr(LocalDateTime localDateTime) {
        return getFirstDayOfYearStr(localDateTime, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getLastDayOfYearStr(LocalDateTime localDateTime) {
        return getLastDayOfYearStr(localDateTime, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getFirstDayOfYearStr(LocalDateTime localDateTime, String pattern) {
        return format(localDateTime.withDayOfYear(1).withHour(0).withMinute(0).withSecond(0), pattern);
    }

    public static String getLastDayOfYearStr(LocalDateTime localDateTime, String pattern) {
        return format(localDateTime.with(TemporalAdjusters.lastDayOfYear()).withHour(23).withMinute(59).withSecond(59), pattern);
    }

    public static String getFirstDayOfMonthStr() {
        return getFirstDayOfMonthStr(LocalDateTime.now());
    }

    public static String getLastDayOfMonthStr() {
        return getLastDayOfMonthStr(LocalDateTime.now());
    }

    public static String getFirstDayOfMonthStr(LocalDateTime localDateTime) {
        return getFirstDayOfMonthStr(localDateTime, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getLastDayOfMonthStr(LocalDateTime localDateTime) {
        return getLastDayOfMonthStr(localDateTime, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getFirstDayOfMonthStr(LocalDateTime localDateTime, String pattern) {
        return format(localDateTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0), pattern);
    }

    public static String getLastDayOfMonthStr(LocalDateTime localDateTime, String pattern) {
        return format(localDateTime.with(TemporalAdjusters.lastDayOfMonth()).withHour(23).withMinute(59).withSecond(59), pattern);
    }

    public static String getFirstDayOfWeekStr() {
        return getFirstDayOfWeekStr(LocalDateTime.now());
    }

    public static String getLastDayOfWeekStr() {
        return getLastDayOfWeekStr(LocalDateTime.now());
    }

    public static String getFirstDayOfWeekStr(LocalDateTime localDateTime) {
        return getFirstDayOfWeekStr(localDateTime, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getLastDayOfWeekStr(LocalDateTime localDateTime) {
        return getLastDayOfWeekStr(localDateTime, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getFirstDayOfWeekStr(LocalDateTime localDateTime, String pattern) {
        return format(localDateTime.with(DayOfWeek.MONDAY).withHour(0).withMinute(0).withSecond(0), pattern);
    }

    public static String getLastDayOfWeekStr(LocalDateTime localDateTime, String pattern) {
        return format(localDateTime.with(DayOfWeek.SUNDAY).withHour(23).withMinute(59).withSecond(59), pattern);
    }

    public static String getStartTimeOfDayStr() {
        return getStartTimeOfDayStr(LocalDateTime.now());
    }

    public static String getEndTimeOfDayStr() {
        return getEndTimeOfDayStr(LocalDateTime.now());
    }

    public static String getStartTimeOfDayStr(LocalDateTime localDateTime) {
        return getStartTimeOfDayStr(localDateTime, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getEndTimeOfDayStr(LocalDateTime localDateTime) {
        return getEndTimeOfDayStr(localDateTime, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getStartTimeOfDayStr(LocalDateTime localDateTime, String pattern) {
        return format(localDateTime.withHour(0).withMinute(0).withSecond(0), pattern);
    }

    public static String getEndTimeOfDayStr(LocalDateTime localDateTime, String pattern) {
        return format(localDateTime.withHour(23).withMinute(59).withSecond(59), pattern);
    }


    public static LocalDateTime plus(LocalDateTime localDateTime, int num, ChronoUnit chronoUnit) {
        return localDateTime.plus((long)num, chronoUnit);
    }

    public static LocalDateTime minus(LocalDateTime localDateTime, int num, ChronoUnit chronoUnit) {
        return localDateTime.minus((long)num, chronoUnit);
    }

    public static Date round(Date date, int field) {
        return DateUtils.round(date, field);
    }

    public static Date round(Date date) {
        return round(date, 13);
    }

    public static boolean isSameSecond(Date start, Date end, boolean round) {
        if (round) {
            start = round(start);
            end = round(end);
        }

        LocalDateTime startDateTime = conversionDate2LocalDateTime(start);
        LocalDateTime endDateTime = conversionDate2LocalDateTime(end);
        return format(startDateTime, "yyyyMMddHHmmss").equalsIgnoreCase(format(endDateTime, "yyyyMMddHHmmss"));
    }

    public static boolean isSameSecond(Date start, Date end) {
        return isSameSecond(start, end, true);
    }

    public static String format(TemporalAccessor temporal, String pattern) {
        DateTimeFormatter dateTimeFormatter = getDf(pattern);
        return dateTimeFormatter.format(temporal);
    }

    public static LocalDateTime parseLocalDateTime(String localDateTimeStr, String pattern) {
        DateTimeFormatter dateTimeFormatter = getDf(pattern);
        return LocalDateTime.parse(localDateTimeStr, dateTimeFormatter);
    }

    public static LocalDate parseLocalDate(String localDateStr, String pattern) {
        DateTimeFormatter dateTimeFormatter = getDf(pattern);
        return LocalDate.parse(localDateStr, dateTimeFormatter);
    }

    public static LocalDateTime conversionDate2LocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }

    public static boolean isValid(String pattern, String value) {
        if (value != null && value.length() != 0) {
            if (pattern.length() != value.length()) {
                return false;
            } else {
                try {
                    getDf(pattern).parse(value);
                    return true;
                } catch (Exception var3) {
                    return false;
                }
            }
        } else {
            return false;
        }
    }

}
